#pragma once


//-----------------------------------------------------------------------------
//															Key-value pairs
//-----------------------------------------------------------------------------
template<typename Key, typename Value>
struct KeyValuePair
{
	typedef Key key_type;
	typedef Value value_type;

	Key key;
	Value val;
};

template<typename Key, typename Value>
bool has_key(Key key, KeyValuePair<Key, Value> container[], uint size)
{
	assert(container);
	assert(size);

	for (uint i = 0; i < size; ++i)
	{
		if (container[i].key == key)
			return true;
	}

	return false;
}

template<typename Key, typename Value>
bool has_value(Value val, KeyValuePair<Key, Value> container[], uint size)
{
	assert(container);
	assert(size);

	for (uint i = 0; i < size; ++i)
	{
		if (container[i].val == val)
			return true;
	}

	return false;
}

template<typename Key, typename Value>
Key key_by_value(Value val, KeyValuePair<Key, Value> container[], uint size)
{
	assert(container);
	assert(size);

	for (uint i = 0; i < size; ++i)
	{
		if (container[i].val == val)
			return container[i].key;
	}

	return container[0].key;
}

template<typename Key, typename Value>
Value value_by_key(Key key, KeyValuePair<Key, Value> container[], uint size)
{
	assert(container);
	assert(size);

	for (uint i = 0; i < size; ++i)
	{
		if (container[i].key == key)
			return container[i].val;
	}

	return container[0].val;
}

#define has_key(key, container) has_key(key, container, sizeof(container))
#define has_value(val, container) has_value(val, container, sizeof(container))
#define key_by_value(val, container) key_by_value(val, container, sizeof(container))
#define value_by_key(key, container) value_by_key(key, container, sizeof(container))

//-----------------------------------------------------------------------------
//																Flags mapping
//-----------------------------------------------------------------------------
inline uint map_flags(uint flags, KeyValuePair<uint, uint> container[], uint size)
{
	assert(container);
	assert(size);

	uint converted = 0;
	for (uint i = 0; i < size; ++i)
		converted |= (flags & container[i].key) ? container[i].val : 0;

	return converted;
}

#define map_flags(flags, container) map_flags(flags, container, sizeof(container))